mint-002

5 Key Degrading Multisig

Motivation

Expanding upon the concept of a 3 key timed multisig, a 5 key timed multisig allows for multiple timelocks to be introduced for additional flexibility.

A timelock can be employed to allow a native 3 of 5 multisig to become 2 of 5, and eventually 1 of 5 for disaster recovery. This can be employed by using a miniscript tresh() with seven conditions:

3 Conditions to be satisfied by:

Base expressions (type B).

timelock: after(int)1 or older(int) - either relative or absolute 2.

timelock: after(int) or older(int)3 - either relative or absolute 4.

Key expressions5 (type K).

pk(key1)6

pk(key2)7

pk(key3)8

pk(key4)9

pk(key5)10

More on Timelock Values

Suggested Relative Block Height Timelocks:

older(32800) Halfway point of block height relative timelock11

older(65535) Maximum duration of a block height relative timelock12

Suggested Relative Epoch Timmelocks:

older(4224680) Approximate Halfway point of epoch time relative timelock13

older(4259839) Maximum duration of an epoch time relative timelock14

Below is a reference diagram on how the 5 Key Time Layered Multisig operates across time:

Example Miniscript Output Descriptor

5 Key Time Lock Multisig

Relative Blockheight Timelock

wsh(thresh(3,pk(XPUB1),s:pk(XPUB2),s:pk(XPUB3),s:pk(XPUB4),s:pk(XPUB5),snu:older(100),snu:older(200)))

Reference Testnet Transaction

Absolute Blockheight Timelock

wsh(thresh(3,pk(XPUB1),s:pk(XPUB2),s:pk(XPUB3),s:pk(XPUB4),s:pk(XPUB5),snu:after(1694563200),snu:after(1694563200)))

Reference Testnet Transaction

Absolute Epochtime Timelock

wsh(thresh(3,pk(XPUB1),s:pk(XPUB2),s:pk(XPUB3),s:pk(XPUB4),s:pk(XPUB5),snu:after(1694563200),snu:after(1694476800)))

Reference Testnet Transaction

Relative Epochtime Timelock

wsh(thresh(3,pk(XPUB1),s:pk(XPUB2),s:pk(XPUB3),s:pk(XPUB4),s:pk(XPUB5),snu:older(4194400),snu:older(4194500)))

Reference Testnet Transaction

(To Add Taproot descriptors once Minitapscript is merged into Core)

Bitcoin Script -->


  1. after(n) = CHECKLOCKTIMEVERIFY 

  2. NUM cannot be 0

  3. older(n) = CHECKSEQUENCEVERIFY 

  4. either relative15 or absolute16 

  5. Key expressions (K Type) take their inputs from the top of the stack, but instead of verifying a condition directly they always push a public key onto the stack, for which a signature is still required to satisfy the expression. A "K" can be converted into a "B" using the c: wrapper (CHECKSIG).  

  6. pk(key1) = c:pk_k(key1) --> <key1> CHECKSIG 

  7. pk(key2) = c:pk_k(key2) --> <key2> CHECKSIG 

  8. pk(key3) = c:pk_k(key3) --> <key3> CHECKSIG 

  9. pk(key4) = c:pk_k(key4) --> <key4> CHECKSIG 

  10. pk(key5) = c:pk_k(key5) --> <key5> CHECKSIG 

  11. ~278 days assuming constant hashrate 

  12. ~455 days assuming constant hashrate 

  13. ~180 days 6 months 

  14. ~388 days 

  15. after(int), older(int): Require that the nLockTime or nSequence value is at least (int). 

  16. after(int), older(int): Require that the nLockTime or nSequence value is at least (int).